import React, { useContext, useEffect, useRef, useState } from 'react';
import {
  Button,
  Card,
  Col,
  Divider,
  Radio,
  Row,
  Slider,
  Typography,
  message,
  Modal,
  Tooltip,
  Space,
} from 'antd';
import { ReloadOutlined, RetweetOutlined } from '@ant-design/icons';
import { SerialContext } from '../context/SerialContext';
import { SerialService } from '../services/SerialService';
import { SerialInfoService } from '../services/SerialInfoService';
import { SerialServoService } from '../services/SerialServoService';
import { SerialMotorService } from '../services/SerialMotorService';
import { WriteService } from '../services/WriteService';
import { handleUpError } from '../utils/errorHandler';
import ServoIdEditorView from '../views/ServoIdEditorView';
import './ServoOperationComponent.css';

const { confirm } = Modal;
const { Text } = Typography;

const ServoOperationComponent: React.FC = () => {
  const ctx = useContext(SerialContext);
  if (!ctx) return null;

  const { serialState, globalModel, servoModel } = ctx;
  const [servoMode, setServoMode] = useState(true);
  const [servoPosition, setServoPosition] = useState(0);
  const [servoSpeed, setServoSpeed] = useState(31);
  const [motorSpeed, setMotorSpeed] = useState(0);
  const [acceleration, setAcceleration] = useState(0);
  const [deceleration, setDeceleration] = useState(0);

  const handleResetConfirm = () => {
    confirm({
      title: '确认要重置舵机吗？',
      content: '该操作将立即重置舵机，请确认已断开负载或注意安全。',
      okText: '确认重置',
      cancelText: '取消',
      okType: 'danger',
      onOk: async () => {
        try {
          await SerialService.reset(
            globalModel.global_serial_id,
            servoModel.servo_id
          );
          message.success('重置成功');
        } catch (err) {
          handleUpError(err);
          message.error('重置失败');
        }
      },
    });
  };

  const loadMode = async () => {
    try {
      const mode = await SerialInfoService.getMode(
        globalModel.global_serial_id,
        servoModel.servo_id
      );
      setServoMode(mode);
      message.success(`获取成功：${mode ? '舵机模式' : '电机模式'}`);
    } catch (err) {
      handleUpError(err);
      message.error('获取失败');
    }
  };

  const handleModeChange = async (newMode: boolean) => {
    const oldMode = servoMode;
    setServoMode(newMode);

    try {
      const url = newMode ? '/servo' : '/motor';
      await SerialService.request(
        url,
        globalModel.global_serial_id,
        servoModel.servo_id
      );
      message.success('模式切换成功');
    } catch (err) {
      handleUpError(err);
      message.error('模式切换失败');
      setServoMode(oldMode);
    }
  };

  const sendAngleSpeed = async (
    newPosition: number,
    newServoSpeed: number,
    newMotorSpeed: number
  ) => {
    if (!serialState.isSerialOpen) return message.error('请先打开串口');
    if (!globalModel.global_serial_id)
      return message.error('未收到 global_serial_id');

    try {
      if (servoMode) {
        await SerialServoService.sendAngleRpm(
          globalModel.global_serial_id,
          servoModel.servo_id,
          newPosition,
          newServoSpeed
        );
      } else {
        await SerialMotorService.sendSpeed(
          globalModel.global_serial_id,
          servoModel.servo_id,
          newMotorSpeed
        );
      }
      message.success('发送成功');
    } catch (err) {
      handleUpError(err);
      message.error('发送失败');
    }
  };

  const requestAccelerationDeceleration = async () => {
    if (!serialState.isSerialOpen) return message.error('请先打开串口');
    if (!globalModel.global_serial_id)
      return message.error('未收到 global_serial_id');

    try {
      await WriteService.sendAccelerationDeceleration(
        globalModel.global_serial_id,
        servoModel.servo_id,
        acceleration,
        deceleration
      );
      message.success('加减速度设置成功');
    } catch (err) {
      handleUpError(err);
    }
  };

  const handleChangeAcceleration = (val: number) => {
    setAcceleration(val);
    requestAccelerationDeceleration();
  };

  const handleChangeDeceleration = (val: number) => {
    setDeceleration(val);
    requestAccelerationDeceleration();
  };

  const centre = () => {
    sendAngleSpeed(150, servoSpeed, motorSpeed);
  };

  const didFetchRef = useRef(false);
  useEffect(() => {
    if (didFetchRef.current) return;
    didFetchRef.current = true;
    loadMode();
  }, []);

  return (
    <div className="servo-operation-container">
      <Card bodyStyle={{ padding: 24 }}>
        {/* 顶部操作区 */}
        <Row justify="space-between" align="middle" className="row-item">
          <Col>
            <ServoIdEditorView />
          </Col>
          <Col>
            <Space size="middle">
              <Tooltip title="重置舵机">
                <RetweetOutlined
                  onClick={handleResetConfirm}
                  className="tooltip-icon"
                />
              </Tooltip>
              <Tooltip title="获取模式">
                <ReloadOutlined onClick={loadMode} className="tooltip-icon" />
              </Tooltip>
            </Space>
          </Col>
        </Row>

        {/* 模式切换 */}
        <Row className="row-item">
          <Col span={24}>
            <Radio.Group
              value={servoMode}
              onChange={(e) => handleModeChange(e.target.value)}
            >
              <Radio value={true}>舵机模式</Radio>
              <Radio value={false}>电机模式</Radio>
            </Radio.Group>
          </Col>
        </Row>

        {/* 舵机控制面板 */}
        {servoMode && (
          <>
            <Divider orientation="left">舵机控制</Divider>
            <Row align="middle" className="row-item">
              <label className="fixed-label">位置：</label>
              <Slider
                className="slider"
                min={0}
                max={300}
                value={servoPosition}
                onChange={setServoPosition}
                onAfterChange={() =>
                  sendAngleSpeed(servoPosition, servoSpeed, motorSpeed)
                }
              />
              <Text className="value-text">{servoPosition}</Text>
            </Row>

            <Row align="middle" className="row-item">
              <label className="fixed-label">速度：</label>
              <Slider
                className="slider"
                min={1}
                max={62}
                value={servoSpeed}
                onChange={setServoSpeed}
                onAfterChange={() =>
                  sendAngleSpeed(servoPosition, servoSpeed, motorSpeed)
                }
              />
              <Text className="value-text">{servoSpeed}</Text>
            </Row>

            <Row justify="center" className="row-item">
              <Button type="primary" onClick={centre}>
                回中
              </Button>
            </Row>
          </>
        )}

        {/* 电机控制面板 */}
        {!servoMode && (
          <>
            <Divider orientation="left">电机控制</Divider>
            <Row align="middle" className="row-item">
              <label className="fixed-label">速度：</label>
              <Slider
                className="slider"
                min={-62}
                max={62}
                value={motorSpeed}
                onChange={setMotorSpeed}
                onAfterChange={() =>
                  sendAngleSpeed(servoPosition, servoSpeed, motorSpeed)
                }
              />
              <Text className="value-text">{motorSpeed}</Text>
            </Row>

            <Row align="middle" className="row-item">
              <label className="fixed-label">加速度：</label>
              <Slider
                className="slider"
                min={0}
                max={255}
                value={acceleration}
                onChange={handleChangeAcceleration}
              />
              <Text className="value-text">{acceleration}</Text>
            </Row>

            <Row align="middle" className="row-item">
              <label className="fixed-label">减速度：</label>
              <Slider
                className="slider"
                min={0}
                max={255}
                value={deceleration}
                onChange={handleChangeDeceleration}
              />
              <Text className="value-text">{deceleration}</Text>
            </Row>
          </>
        )}
      </Card>
    </div>
  );
};

export default ServoOperationComponent;
